home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************************
-
- This code fragment illustrates the unsuccessful attempt to directly
- modify the IOPM base address. This code would appear in a kernel
- mode device driver. Refer to the GIVEIO.C listing for a complete
- device driver example.
-
- *********************************************************************/
-
- /*
- * Make sure our structure is packed properly, on byte boundary, not
- * on the default doubleword boundary.
- */
- #pragma pack(push,1)
-
- /*
- * Structure of a GDT (global descriptor table) entry. From
- * processor manual.
- */
- typedef struct {
- unsigned limit : 16;
- unsigned baselo : 16;
- unsigned basemid : 8;
- unsigned type : 4;
- unsigned system : 1;
- unsigned dpl : 2;
- unsigned present : 1;
- unsigned limithi : 4;
- unsigned available : 1;
- unsigned zero : 1;
- unsigned size : 1;
- unsigned granularity : 1;
- unsigned basehi : 8;
- } GDTENT;
-
- /*
- * Structure of the 48 bits of the GDT register that are stored
- * by the SGDT instruction.
- */
- typedef struct {
- unsigned short limit;
- GDTENT *base;
- } GDTREG;
-
- #pragma pack(pop)
-
- /*
- * This code demonstrates the brute force approach to modifying
- * the IOPM base. The IOPM base is stored as a two byte integer
- * at offset 0x66 within the TSS, as documented in the processor
- * manual. In Windows NT, the IOPM is stored within the TSS
- * starting at offset 0x88, and going for 0x2004 bytes. This is
- * not documented anywhere, and was determined by inspection.
- * The code here puts some 0's into the IOPM so that we
- * can try to access some I/O ports, then modifies the IOPM base
- * address.
- *
- * This code is unsuccessful because NT overwrites the IOPM
- * base on each process switch.
- */
- void GiveIO()
- {
- GDTREG gdtreg;
- GDTENT *g;
- short TaskSeg;
- char *TSSbase;
- int i;
-
- _asm str TaskSeg; // get the TSS selector
- _asm sgdt gdtreg; // get the GDT address
-
- g = gdtreg.base + (TaskSeg >> 3); // get the TSS descriptor
-
- // get the TSS address
- TSSbase = (PVOID)(g->baselo | (g->basemid << 16)
- | (g->basehi << 24));
-
- for(i=0; i < 16; ++i) // poke some 0's into the
- TSSbase[0x88 + i] = 0; // IOPM
-
- // set IOPM base to 0x88
- *((USHORT *)(TSSbase + 0x66)) = 0x88;
- }
-
-